﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.WebControls;
using SlamCms.SharePoint.UserManagement.Data;
using System.Data.EntityClient;
using Slam;
using Slam.Configuration;
using Microsoft.SharePoint;
using SlamCms.SharePoint.Data;
using System.Xml.Linq;
using System.Data.Linq;
using System.Linq;
using System.Collections.Generic;
using SlamCms.SharePoint.Core;
using System.Web;
using SlamCms.Configuration;
using Slam.FieldTypes;

namespace SlamCms.SharePoint.FieldTypes
{
	[SlamFieldAction]
	public partial class ZoneSiteLookupFieldControl : SlamFieldControl
	{
		//protected Label lblFieldValue;

		//private const string connection = "Database=Site10001Db;Data Source=Spsdev01\\Sharepoint;User Id=MyDbUser;Password=Pass01";
		private const string connection = "Database=KnowledgeCenter01;Data Source=Spsdev01\\Sharepoint;User Id=MyDbUser;Password=Pass01";
		//string connectionString = "Database=KnowledgeCenter;Data Source=spf2010dev;User ID=HabitatUser;Password=94efb35d";

		protected System.Web.UI.HtmlControls.HtmlSelect selectZoneSites;

		public override object Value
		{
			get
			{
				this.EnsureChildControls();
				return this.selectZoneSites.Items[selectZoneSites.SelectedIndex].Value;
			}
		}


		protected override string DefaultTemplateName
		{
			get
			{
				return "SlamCMSZoneSiteLookupFieldControl";
			}
		}

		private string fieldValue;

		public string FieldValue
		{
			get { return fieldValue; }
			set { fieldValue = value; }
		}

		protected override void CreateChildControls()
		{
			if (Field == null)
				return;

			base.CreateChildControls();

			if (ControlMode == SPControlMode.Display)
				return;

			//if (!base.IsFieldValueCached)
			//{
			//    lblFieldValue = (Label)TemplateContainer.FindControl("lblFieldValue");
			//    lblFieldValue.Text = this.FieldValue;
			//}

			this.selectZoneSites = (System.Web.UI.HtmlControls.HtmlSelect)TemplateContainer.FindControl("selectZoneSites");
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			
			Page.ClientScript.RegisterClientScriptInclude("jquery", ResolveUrl("~/_layouts/inc/jquery-1.6.2.min.js"));
			Page.ClientScript.RegisterClientScriptInclude("chosen", ResolveUrl("~/_layouts/inc/chosen.jquery.js"));

			if (ControlMode == SPControlMode.Display)
				return;

            Dictionary<Guid, string> selectSites = GetSites();

            foreach (KeyValuePair<Guid, string> site in selectSites)
			{
				this.selectZoneSites.Items.Add(new ListItem(site.Value,site.Key.ToString()));
			}

			if (this.ItemFieldValue != null)
			{
				var item = selectZoneSites.Items.FindByValue(ItemFieldValue.ToString());
				if (item != null)
					item.Selected = true;
			}
		}

		protected override void OnInit(EventArgs e)
		{	
			base.OnInit(e);

			Slam.SlamContext.Get(List).Actions.Register(SlamEvent.PostSave, listItem => SaveZoneSiteAssociations());
		}

        private Dictionary<Guid, string> GetSites()
		{
            Dictionary<Guid, string> relevantSites = new Dictionary<Guid, string>();

			UpdateSites();

			var sites = (from item in SlamCmsContext.Data.Sites
						 where !item.Name.Equals(String.Empty) && !item.Name.Equals("GlobalSettings")
						 select item).ToList();

			foreach (SlamCms.Data.Site site in sites)
			{
				//relevantSites.Add(site.Title, site.SiteId);
                relevantSites.Add(site.SiteId, site.Title);
			}

			// Use this with SlamCmsContext Working
			//var sites = (from item in SlamCmsContext.DataContext.Sites
			//             where !item.Name.Equals(String.Empty) && !item.Name.Equals("GlobalSettings")
			//             select item).ToList();

			//foreach (SlamCms.Data.Site site in sites)
			//{
			//    relevantSites.Add(site.Title, site.SiteId);
			//}

			return relevantSites;
		}

		private void UpdateSites()
		{
			//Entities context = GetContext(ConfigurationManager.Environment.ConnectionStrings["Default"].ToString());
			var slamSiteCollections = (from item in SlamCmsContext.Entities.SiteCollections
									   select item).ToList();

            var slamSites = (from item in SlamCmsContext.Entities.Sites
							 select item).ToList();

			List<Site> sitesToAdd = new List<Site>();

			if (slamSiteCollections.Count() > 0)
			{
				foreach (SiteCollection siteCol in slamSiteCollections)
				{
					  sitesToAdd.AddRange(GetNewSites(siteCol, slamSites));
				}
			}
			else
			{
				SiteCollection newSiteCollection = new SiteCollection();
				newSiteCollection.SiteCollectionID = SPContext.Current.Site.ID;
				newSiteCollection.ServerRelativeUrl = SPContext.Current.Site.ServerRelativeUrl;
                SlamCmsContext.Entities.AddToSiteCollections(newSiteCollection);
                SlamCmsContext.Entities.SaveChanges();
				sitesToAdd.AddRange(GetNewSites(newSiteCollection, slamSites));
			}

			if (sitesToAdd.Count > 0)
			{
				foreach (Site newSite in sitesToAdd)
				{
                    SlamCmsContext.Entities.AddToSites(newSite);
				}
                SlamCmsContext.Entities.SaveChanges();
			}
		}

		private List<Site> GetNewSites(SiteCollection slamSiteCollection, List<Site> slamSites)
		{ 
			List<Site> newSites = new List<Site>();
			
				try
				{
					using (SPSite site = new SPSite(slamSiteCollection.SiteCollectionID))
					{
						foreach (SPWeb web in site.AllWebs)
						{
							var slamSite = (from item in slamSites
											where item.SiteID.Equals(web.ID)
											select item).FirstOrDefault();

							if (slamSite == null)
							{
								Site newSite = new Site();
								newSite.SiteID = web.ID;
								newSite.Title = web.Title;
								newSite.Name = web.Name;
								newSite.Url = web.ServerRelativeUrl.Substring(site.ServerRelativeUrl.Length);
								newSite.SiteCollection = slamSiteCollection;
								newSites.Add(newSite);
							}
						}
					}
				}
				catch (System.IO.FileNotFoundException)
				{
					// In case there is no site collection with the specified ID.
				}
			
			return newSites;
		
		}

        //private Entities GetContext(string connectionString)
        //{

        //    string dataSchema = "dbo";

        //    string modelName = "Data.SlamCms";
        //    EntityConnectionStringBuilder entityConnection = new EntityConnectionStringBuilder();
        //    entityConnection.Provider = "System.Data.SqlClient";
        //    if (!connectionString.Contains("Persist Security Info"))
        //    {
        //        connectionString = connectionString.TrimEnd(';') + ";Persist Security Info=True;";
        //    }
        //    entityConnection.ProviderConnectionString = connectionString;
        //    entityConnection.Metadata = String.Format("res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl", modelName);


        //    //Create object context and set schema
        //    Entities context = new Entities(entityConnection.ToString());
        //    context.SetStoreSchema(modelName, dataSchema);

        //    return context;

        //}

		//private List<Site> GetNewSites(SPSite siteCol, List<Site> slamSites)
		//{
		//    //Dictionary<string, Guid> relevantSites = new Dictionary<string, Guid>();
		//    List<Site> newSites = new List<Site>();

		//    foreach (SPWeb web in siteCol.AllWebs)
		//    {
		//        var site = (from item in slamSites
		//                    where item.SiteID.Equals(web.ID)
		//                    select item).FirstOrDefault();

		//        if (site == null)
		//        {
		//            Site newSite = new Site();
		//            newSite.Title = web.Title;
		//            newSite.Name = web.Name;
		//            newSite.Url = web.ServerRelativeUrl.Substring(siteCol.ServerRelativeUrl.Length);
		//            newSite.Site
				
		//        }
					
		//    }
		//    return relevantSites;
		//}


		#region events

		protected void SaveZoneSiteAssociations()
		{
			//Entities context = GetContext(ConfigurationManager.Environment.ConnectionStrings["Default"].ToString());

            var slamSites = (from item in SlamCmsContext.Entities.Sites.Include("SiteCollection")
							 select item).ToList();

			string zoneID = SPContext.Current.Item["SLAM ID"].ToString();
			//zoneID = "28e";

			Guid siteId = new Guid((string)this.Value);

			var slamSite = (from item in slamSites
							where item.SiteID.Equals(siteId)
							select item).FirstOrDefault<Site>();

			// Get SiteCollection ID.
			Guid siteCollectionID = Guid.Empty;
			if(slamSite != null)
			{
                var slamSiteCol = (from item in SlamCmsContext.Data.SiteCollections
								   where item.SiteCollectionId.Equals(slamSite.SiteCollection.SiteCollectionID)
								   select item).FirstOrDefault();

				if (slamSiteCol != null)
                    siteCollectionID = slamSiteCol.SiteCollectionId;
			}

			List<Guid> siteIDs = new List<Guid>();

			if (siteCollectionID != Guid.Empty)
			{
				using (SPSite siteCol = new SPSite(siteCollectionID))
				{
					//using (SPWeb site = siteCol.AllWebs[slamSite.SiteId])
					using (SPWeb site = siteCol.AllWebs[slamSite.SiteID])
					{
						siteIDs.Add(site.ID);
						siteIDs.AddRange(GetSubSiteIDs(site.Webs));
					}
				}
			}

            var zone = (from item in SlamCmsContext.Entities.Zones.Include("Sites")
						where item.ZoneID.Equals(zoneID)
						select item).FirstOrDefault();

			if (zone != null)
			{
				// Clear Records from ZoneSite
				zone.Sites.Clear();
                SlamCmsContext.Entities.SaveChanges();

				// Add elements association
				foreach (Guid id in siteIDs)
				{
					zone.Sites.Add(slamSites.First(s => s.SiteID.Equals(id)));
				}
                SlamCmsContext.Entities.SaveChanges();
			}
		}

		private List<Guid> GetSubSiteIDs(SPWebCollection subSites)
		{
			List<Guid> ids = new List<Guid>();
			if (subSites.Count > 0)
			{
				
				foreach (SPWeb child in subSites)
				{
					ids.Add(child.ID);
					//if (child.Webs.Count > 0)
					ids.AddRange(GetSubSiteIDs(child.Webs));
				}
			}
			return ids;
		}
		
		#endregion


	}
}
